let openDebugger = false;
const isEmpty = (value) => {
    return value === null || value === undefined || value === '';
};

const prettyPrint = (title, text, color) => {
    if (openDebugger) {
        let logString = `%c ${title} %c ${text} %c`
        if (typeof text === 'object') {
            // logString = `%c ${title} %c%O ${text} %c`
        }

        console.log(
            logString,
            `background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`,
            `border:1px solid ${color}; padding: 1px; border-radius: 0 2px 2px 0; color: ${color};`,
            'background:transparent'
        );
    }
};

class Logger {
    constructor(isDev) {
        if (isDev !== undefined) openDebugger = isDev;
    }

    log(textOrTitle, content = '') {
        if (isEmpty(content)) {
            prettyPrint('Log', textOrTitle, '#bebfc5');
        } else {
            prettyPrint(textOrTitle, content, '#909399');
        }
    }

    info(textOrTitle, content = '') {
        if (isEmpty(content)) {
            prettyPrint('Info', textOrTitle, '#3a62b0');
        } else {
            prettyPrint(textOrTitle, content, '#3a62b0');
        }
    }

    error(textOrTitle, content = '') {
        const title = isEmpty(content) ? 'Error' : textOrTitle;
        const text = isEmpty(content) ? textOrTitle : content;
        prettyPrint(title, text, '#F56C6C');
    }

    warning(textOrTitle, content = '') {
        const title = isEmpty(content) ? 'Warning' : textOrTitle;
        const text = isEmpty(content) ? textOrTitle : content;
        prettyPrint(title, text, '#E6A23C');
    }

    success(textOrTitle, content = '') {
        const title = isEmpty(content) ? 'Success ' : textOrTitle;
        const text = isEmpty(content) ? textOrTitle : content;
        prettyPrint(title, text, '#67C23A');
    }
}

let logger;

/**
 * 用于帮助在页面生命周期中操作组件
 *
 * @example:
 * // 实例化工具类
 * const helper = new Helper(this)
 * // 获取组件
 * const formRecord = helper.get('formRecord', true);
 * // 获取 logger 单例
 * const logger = helper.createLogger(true);
 *
 * // 使用组件
 * formRecord.widgetObj.asyncSelectOptions('personName', result);
 */
class Helper extends Logger {
    apiPage;
    constructor(widget, debug) {
        super(debug)
        this.apiPage = widget?.getApiPage ? widget?.getApiPage() : widget || {}
    }

    /**
     * 创建 logger 单例
     *
     * @param debug
     * @return {Logger}
     */
    createLogger (debug) {
        return logger || (logger = new Logger(debug));
    }

    /**
     * 根据组件名称 获取组件
     *
     * @param widgetName 组件别名
     * @param show todo 显示 or 隐藏 -------> ** 必须显示指定才能生效 **
     * @returns {ApiWidgetInterface} 返回组件
     */
    get = (widgetName, show) => {
        try {
            const formRecord = this.apiPage.getApiWidgetByAliasName(widgetName);
            if (show !== void 0) {
                if (show) {
                    formRecord?.showWidget();
                } else {
                    formRecord?.hideWidget();
                }
            }
            return formRecord
        } catch (error) {
            console.error(error)
        }
    }

    /**
     * 显示组件 and 返回组件
     *
     * @param widgetName 组件别名
     * @returns {ApiWidgetInterface} 返回组件
     */
    show = (widgetName) => {
        try {
            const formRecord = this.apiPage.getApiWidgetByAliasName(widgetName);
            formRecord?.showWidget();
            return formRecord
        } catch (error) {
            console.error(error)
        }
    }

    /**
     * 隐藏组件 and 返回组件
     *
     * @param widgetName 组件别名
     * @returns {ApiWidgetInterface} 返回组件
     */
    hide = (widgetName) => {
        try {
            const formRecord = this.apiPage.getApiWidgetByAliasName(widgetName);
            formRecord?.hideWidget();
            return formRecord
        } catch (error) {
            console.error(error)
        }
    }

    /**
     * 根据组件名称 获取组件
     *
     * @param widgetName 组件别名
     * @param show todo 显示 or 隐藏 -------> ** 必须显示指定才能生效 **
     * @returns {ApiWidgetInterface} 返回组件
     */
    getByCls = (widgetName, show) => {
        try {
            const formRecord = this.apiPage.getApiWidgetsByClassName(widgetName);
            if (show !== void 0) {
                if (show) {
                    formRecord?.forEach(wgt => wgt.showWidget());
                } else {
                    formRecord?.forEach(wgt => wgt.hideWidget());
                }
            }
            return formRecord
        } catch (error) {
            console.error(error)
        }
    }

    /**
     * 显示组件 and 返回组件
     *
     * @param widgetName 组件别名
     * @returns {ApiWidgetInterface} 返回组件
     */
    showByCls = (widgetName) => {
        try {
            const formRecord = this.apiPage.getApiWidgetsByClassName(widgetName);
            formRecord?.forEach(wgt => wgt.showWidget());
            return formRecord
        } catch (error) {
            console.error(error)
        }
    }

    /**
     * 隐藏组件 and 返回组件
     *
     * @param widgetName 组件别名
     * @returns {ApiWidgetInterface} 返回组件
     */
    hideByCls = (widgetName) => {
        try {
            const formRecord = this.apiPage.getApiWidgetsByClassName(widgetName);
            formRecord?.forEach(wgt => wgt.hideWidget());
            return formRecord
        } catch (error) {
            console.error(error)
        }
    }

    /**
     * 获取所有变量
     *
     * @returns {*}
     */
    getVariables = () => {
        return this.apiPage?.getVariables?.()
    }
    /**
     * 获取变量
     *
     * @param name
     * @returns {*}
     */
    getVariable = (name) => {
        return this.apiPage?.getVariables?.().find(v => v.name === name)?.value;
    }

    /**
     * 设置变量
     *
     * @param name
     * @param value
     * @returns {*}
     */
    setVariable = (name, value) => {
        if (typeof value === 'object') value = JSON.stringify(value);
        this.apiPage?.setVariables?.([{ name, value }]);
    }

    /**
     * 设置/获取变量
     *
     * 获取: variable(name)
     * 设置: variable(name, value)
     *
     * @param name
     * @param value
     * @returns {*}
     */
    variable = (name, value) => {
        if (value) {
            this.setVariable(name, value);
        } else {
            return this.getVariable(name);
        }
    }

    /**
     * 解码数据
     *
     * @param data
     * @return {any}
     */
    parse = (data) => {
        try {
            return JSON.parse(data)
        } catch (e) {
            console.error(e)
        }
    }

    /**
     * 解码变量数据
     *
     * @param name
     * @return {any}
     */
    parseVariable = (name) => {
        // 获取变量
        const data = this.getVariable(name);
        // 返回解码
        return this.parse(data)
    }

    /**
     * 确认框
     *
     * @param content
     * @param options: {
     *      title
     *      cancelText
     *      okText
     *      cancel
     *      ok
     * }
     */
    confirm (content = '实例内容', { title, cancelText = '取消', okText = '确定', cancel, ok } = {}) {
        const $template = $(`
            <div class="layui-layer-shade" style="z-index: 19891014; background-color: rgb(0, 0, 0); opacity: 0.3;"></div>
            <div class="root-confirm">

                <div class="root-confirm-body">
                    <div class="root-confirm-body-context">${ content }</div>
                    <div class="root-confirm-footer">
                        <button class="root-confirm-footer-btn root-confirm-footer-btn-cancel" style="">${ cancelText }</button>
                        <button class="root-confirm-footer-btn root-confirm-footer-btn-ok">${ okText }</button>
                    </div>
                </div>
            </div>
        `);
        if (title) {
            $template.find('.root-confirm-body').before(`
                <div class="root-confirm-header">
                    <span class="root-confirm-title" style="">${ title }</span>
                </div>
            `)
        }

        $('body').append($template);

        function onConfirmCancel () {
            $template.remove();
            cancel?.()
        }

        function onConfirmOk () {
            ok?.($template)
        }

        $template.on('click', '.root-confirm-footer-btn-cancel', onConfirmCancel)
        $template.on('click', '.root-confirm-footer-btn-ok', onConfirmOk)
    }
}